/*
 * c11.c - C11 标准特性示例
 * 
 * C11 (ISO/IEC 9899:2011) 是C语言的第三个官方标准，引入了多项现代化特性
 * 本示例展示了C11标准特有的功能
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdalign.h>
#include <stdnoreturn.h>
//#include <threads.h>
//threads.h 缺失原因：MinGW-w64 未完整实现 C11 标准线程库，依赖动态库或手动配置。
#include <stdatomic.h>
#include <uchar.h>
#include <stdint.h>

// _Noreturn 关键字 - C11新特性
// 表示函数从不返回
_Noreturn void fatal_error(const char *message) {
    fprintf(stderr, "致命错误: %s\n", message);
    exit(EXIT_FAILURE);
    // 下面这行永远不会执行
    printf("这行代码永远不会执行\n");
}

// _Generic 泛型选择表达式 - C11新特性
#define get_type(x) _Generic((x), \
    int: "整型", \
    float: "浮点型", \
    double: "双精度浮点型", \
    char: "字符型", \
    char*: "字符串", \
    default: "其他类型" \
)

void generic_example() {
    int i = 42;
    float f = 3.14f;
    double d = 2.718;
    char c = 'A';
    char *s = "Hello C11";
    
    printf("%d 是 %s\n", i, get_type(i));
    printf("%f 是 %s\n", f, get_type(f));
    printf("%lf 是 %s\n", d, get_type(d));
    printf("%c 是 %s\n", c, get_type(c));
    printf("%s 是 %s\n", s, get_type(s));
}

// 对齐说明符和 alignas 宏 - C11新特性
void alignment_example() {
    // 按16字节对齐
    alignas(16) char buffer[128];
    
    // 检查对齐要求
    printf("buffer对齐要求: %zu 字节\n", alignof(buffer));
    
    // 按最大对齐要求的结构体
    struct AlignedStruct {
        char c;
        alignas(16) double d;  // 强制16字节对齐
    };
    
    struct AlignedStruct as;
    printf("AlignedStruct对齐要求: %zu 字节\n", alignof(as));
    printf("AlignedStruct大小: %zu 字节\n", sizeof(as));
}

// 原子操作 - C11新特性
void atomic_example() {
    atomic_int counter = ATOMIC_VAR_INIT(0);
    
    // 原子地增加计数器
    atomic_fetch_add(&counter, 1);
    atomic_fetch_add(&counter, 1);
    
    // 原子地读取计数器值
    int value = atomic_load(&counter);
    
    printf("原子计数器值: %d\n", value);
    
    // 比较并交换
    int expected = 2;
    int desired = 100;
    if (atomic_compare_exchange_strong(&counter, &expected, desired)) {
        printf("比较并交换成功，新值: %d\n", atomic_load(&counter));
    }
}

// 线程支持 - C11新特性
// 注意：部分编译器可能需要特定编译选项才能支持线程
// int thread_func(void *arg) {
//     int thread_id = *((int *)arg);
//     printf("线程 %d 正在运行\n", thread_id);
//     return 0;
// }

// void threads_example() {
//     thrd_t thread1, thread2;
//     int id1 = 1, id2 = 2;
    
//     // 创建两个线程
//     if (thrd_create(&thread1, thread_func, &id1) != thrd_success) {
//         printf("创建线程1失败\n");
//     }
    
//     if (thrd_create(&thread2, thread_func, &id2) != thrd_success) {
//         printf("创建线程2失败\n");
//     }
    
//     // 等待线程结束
//     thrd_join(thread1, NULL);
//     thrd_join(thread2, NULL);
    
//     printf("所有线程已完成\n");
// }

// Unicode支持 - C11新特性
void unicode_example() {
    // char16_t 和 char32_t 类型
    char16_t utf16_str[] = u"你好，C11!";
    char32_t utf32_str[] = U"Unicode示例";
    
    //  UTF-8 字符串字面量前缀 u8
    const char *utf8_str = u8"UTF-8编码的字符串";
    
    printf("UTF-8字符串: %s\n", utf8_str);
    printf("UTF-16和UTF-32字符串在标准输出中显示需要特殊处理\n");
}

// 静态断言 - C11新特性
// 在编译时检查条件
_Static_assert(sizeof(int) >= 4, "int类型至少需要4字节");
_Static_assert(sizeof(long long) == 8, "long long类型必须是8字节");

void static_assert_example() {
    printf("静态断言通过，所有编译时检查条件满足\n");
}

// 安全函数 - C11新特性
void safe_functions() {
    char dest[10];
    const char *src = "This is a too long string";
    
    // 使用安全版本的字符串复制函数
    // 如果目标缓冲区不够大，会返回错误并置零目标缓冲区
    strcpy_s(dest, sizeof(dest), src);
    
    printf("目标字符串: %s\n", dest);
}

int main() {
    printf("=== C11 Standard Features ===\n\n");
    
    // 测试泛型选择表达式
    generic_example();
    printf("\n");
    
    // 测试对齐说明符
    alignment_example();
    printf("\n");
    
    // 测试原子操作
    atomic_example();
    printf("\n");
    
    // 测试Unicode支持
    unicode_example();
    printf("\n");
    
    // 测试静态断言
    static_assert_example();
    printf("\n");
    
    // 测试_Noreturn函数
    printf("即将调用永不返回的函数...\n");
    // 取消下面的注释会导致程序终止
    // fatal_error("测试_Noreturn关键字");
    printf("如果看到这行，说明上面的fatal_error函数没有被调用\n\n");
    
    // 测试线程支持
    // 注意：取消下面的注释需要确保编译器支持C11线程
    // threads_example();
    // printf("\n");
    
    // 测试安全函数
    // 注意：有些编译器可能需要特定编译选项才能支持安全函数
    // safe_functions();
    
    return 0;
}